#include "comm.h"
#include "car_test.h"

static comm_tcb_t udp_tcb;

void udp_thread(void *pdata)
{
    int ret;
    cJSON *recvjson;
    struct sockaddr_in serverAddr;
    struct sockaddr_in clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);

    pdata = pdata;

    memset(&udp_tcb, 0, sizeof(comm_tcb_t));
    memset(&serverAddr, 0, sizeof(serverAddr));
    memset(&clientAddr, 0, sizeof(clientAddr));

    udp_tcb.sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // TCP socket

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(3861);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    ret = bind(udp_tcb.sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    printf("bind scockfd ok  %d\r\n", ret); 
    if (ret < 0) {
        printf("bind failed,45hao test  %ld!\r\n", ret);
        printf("do_cleanup...\r\n");
        close(udp_tcb.sockfd);
    }
    
    //�󶨶˿ں�

    while(1)
    {
         struct sockaddr_in addrClient;

        ret = recvfrom(udp_tcb.sockfd, udp_tcb.recvline, sizeof(udp_tcb.recvline), 0, (struct sockaddr *)&addrClient, &clientAddrLen);    
        if(ret>0)
        {
            char *pClientIP =inet_ntoa(addrClient.sin_addr);

            printf("%s-%d(%d) says:%s\n",pClientIP,ntohs(addrClient.sin_port),addrClient.sin_port, udp_tcb.recvline);

            //进行json解析
            recvjson = cJSON_Parse(udp_tcb.recvline);

            if(recvjson != NULL)
            {
                
                if(cJSON_GetObjectItem(recvjson, "cmd")->valuestring != NULL)
                {
                    printf("cmd : %s\r\n", cJSON_GetObjectItem(recvjson, "cmd")->valuestring);
                    
                    if(strcmp("forward", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        //ǰ��
                        printf("car forward");
                        set_car_status(CAR_STATUS_FORWARD);
                    }

                    if(strcmp("backward", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        //����
                        printf("car backward");
                        set_car_status(CAR_STATUS_BACKWARD);
                    }

                    if(strcmp("left", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        //��ת
                        printf("car left");
                        set_car_status(CAR_STATUS_LEFT);
                    }

                    if(strcmp("right", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        //��ת
                        printf("car right");
                        set_car_status(CAR_STATUS_RIGHT);
                    }

                    if(strcmp("stop", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        //ֹͣ
                        printf("car stop");
                        set_car_status(CAR_STATUS_STOP);
                    }
                }
                
                if(cJSON_GetObjectItem(recvjson, "mode")->valuestring != NULL)
                {
                    if(strcmp("step", cJSON_GetObjectItem(recvjson, "mode")->valuestring) == 0)
                    {
                        set_car_mode(CAR_MODE_STEP);
                        printf("mode step\r\n");
                    }

                    if(strcmp("alway", cJSON_GetObjectItem(recvjson, "mode")->valuestring) == 0)
                    {
                        set_car_mode(CAR_MODE_ALWAY);
                        printf("mode alway\r\n");
                    }
                }

                // if(cJSON_GetObjectItem(recvjson, "proto")->valuestring != NULL)
                // {
                //     if(strcmp("tcp", cJSON_GetObjectItem(recvjson, "proto")->valuestring) == 0)
                //     {
                //         osDelay(100);
                //         printf("======== Protocol: TCP ========\r\n");
                //         set_comm_mode(COMM_PROTOCOL_TCP);
                //     }

                //     if(strcmp("udp", cJSON_GetObjectItem(recvjson, "proto")->valuestring) == 0)
                //     {
                //         osDelay(100);
                //         printf("======== Protocol: UDP ========\r\n");
                //         set_comm_mode(COMM_PROTOCOL_UDP);
                //     }
                // }

                cJSON_Delete(recvjson);
            }
		}

        osDelay(1);
    }
}


void start_udp_thread(void)
{
    osThreadAttr_t attr;

    attr.name = "udp_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 2048;
    attr.priority = 36;

    udp_tcb.udp_thd = osThreadNew((osThreadFunc_t)udp_thread, NULL, &attr);
    
    if (udp_tcb.udp_thd == NULL) {
        printf("[udp_thread] Falied to create udp_thread!\n");
        return;
    }
    printf("[udp_thread] Success to create udp_thread!\n");
}

void cancel_udp_thread(void)
{
    if(udp_tcb.udp_thd != NULL){
        printf("cancel_udp_thread\r\n");
        if (udp_tcb.sockfd != 0) {
            close(udp_tcb.sockfd);
        }

        osThreadTerminate(udp_tcb.udp_thd);
        printf("[udp_thread] cancel udp_thread!\n");
        return;
    }
    printf("[udp_thread] udp_thread not live!\n");
}
